package com.googlecode.gwtbb.client.only.widget.display.forum;

import com.google.gwt.user.client.ui.*;
import com.googlecode.gwtbb.client.only.ClientOnlyMessages;
import com.googlecode.gwtbb.client.only.GwtbbCmess;
import com.googlecode.gwtbb.client.only.glue.PathUtils;
import com.googlecode.gwtbb.client.only.glue.TokenOwner;
import com.googlecode.gwtbb.client.only.remote.ClientSession;
import com.googlecode.gwtbb.client.only.remote.NiceCallback;
import com.googlecode.gwtbb.client.only.remote.forum.ForumServiceProxy;
import com.googlecode.gwtbb.client.only.widget.SessionWidget;
import com.googlecode.gwtbb.client.only.widget.basic.ModuleHeader;
import com.googlecode.gwtbb.client.only.widget.form.CompleteProcessListener;
import com.googlecode.gwtbb.client.only.widget.form.FormSuccessPopupPanel;
import com.googlecode.gwtbb.client.only.widget.form.LoginProtectedLink;
import com.googlecode.gwtbb.client.only.widget.form.ProcessEvent;
import com.googlecode.gwtbb.client.only.widget.form.forum.CreateReplyForm;
import com.googlecode.gwtbb.client.shared.entity.forum.Forum;
import com.googlecode.gwtbb.client.shared.entity.forum.Post;
import com.googlecode.gwtbb.client.shared.remote.forum.ForumPosts;

import java.util.List;

/**
 * @author Abraham Grief
 * @version $Id$
 * @since Jul 7, 2008
 */
public class ThreadDetail extends SessionWidget implements TokenOwner {
	protected static final ClientOnlyMessages c = GwtbbCmess.instance();

	private VerticalPanel postDisplay;
	private ForumLink forumLink;
	private Label threadLabel;
	private CreateReplyForm createReplyForm;
	private Forum forum;
	private Post thread;


	public ThreadDetail(ClientSession session) {
		super(session);

		VerticalPanel mainPanel = new VerticalPanel();
		initWidget(mainPanel);
		mainPanel.setWidth("100%");

		ModuleHeader moduleHeader = new ModuleHeader();
		mainPanel.add(moduleHeader);

		HorizontalPanel header = new HorizontalPanel();
		moduleHeader.setHeaderLeft(header);
		header.setStylePrimaryName("gwtbb-header");
		header.add(new ForumsLink());
		header.add(new HTML(c.logicalPathSeparator()));
		forumLink = new ForumLink(null);
		header.add(forumLink);
		header.add(new HTML(c.logicalPathSeparator()));
		threadLabel = new Label();
		header.add(threadLabel);

		createReplyForm = new CreateReplyForm(session);
		createReplyForm.setWidth("100%");
		createReplyForm.getCancelButton().addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				hideReplyForm();
			}
		});
		new FormSuccessPopupPanel(createReplyForm);
		createReplyForm.getCompleteProcessListenerCollection().addCompleteProcessListener(new CompleteProcessListener() {
			public void onProcessCompletion(ProcessEvent processEvent) {
				empty();
				fill(thread.getId());
			}
		});
		HorizontalPanel newPostPanel = new HorizontalPanel();
		moduleHeader.setHeaderRight(newPostPanel);
		newPostPanel.add(new LoginProtectedLink(getSession(), c.createReplyLink()) {
			public void ifLoggedIn() {
				if (forum != null && thread != null) {
					createReplyForm.setForumId(forum.getId());
					createReplyForm.setThreadId(thread.getId());
					createReplyForm.reset();
					createReplyForm.setVisible(true);
				}
			}
		});

		postDisplay = new VerticalPanel();
		mainPanel.add(postDisplay);
		postDisplay.setWidth("100%");
		postDisplay.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
	}

	public boolean owns(String token) {
		return token != null && token.contains(TokenOwner.DELIM_STR);
	}

	public void serve(String token) {
		token = PathUtils.getSubToken(token);  // because forum subtoken precedes thread subtoken
		String threadIdStr = PathUtils.getTokenStart(token);
		empty();
		try {
			fill(Long.valueOf(threadIdStr));
		} catch (NumberFormatException e) {
			displayError(c.invalidToken());
		}
	}

	private void displayError(String errorMsg) {
		postDisplay.add(new Label(errorMsg));
	}

	private void empty() {
		forumLink.clear();
		postDisplay.clear();
		hideReplyForm();
		postDisplay.add(createReplyForm);
		threadLabel.setText("");
	}

	private void fill(Long threadId) {
		ForumServiceProxy.instance().getForumThreadPosts(threadId, new NiceCallback<ForumPosts>() {
			public void handle(ForumPosts forumPosts) {
				forum = forumPosts.getForum();
				forumLink.setForum(forum);

				if (forum != null) {
					List<Post> posts = forumPosts.getPosts();
					if (posts != null && !posts.isEmpty()) {
						thread = posts.get(0);
						threadLabel.setText(thread.getSubject());

						for (Post post : posts) {
							PostDetail postDetail = new PostDetail(post);
							postDisplay.add(postDetail);
							postDetail.setWidth("100%");
						}
					} else
						displayError(c.noPosts());
				} else
					displayError(c.invalidForum());
			}
		});
	}

	private void hideReplyForm() {
		createReplyForm.setVisible(false);
	}
}
